#!/usr/bin/python3
# -*- coding: utf-8 -*-

import logging, aiohttp_jinja2, os
import dfs_client

from aiohttp import web, hdrs
from coreweb import query_string
from settings import config

routes = web.RouteTableDef()

@routes.get('/pan/root/load')
async def load_root(request):
    params = query_string(request)
    path = params.get('path', '/root')
    data = dfs_client.goto_dir(path)
    # session = db.create_session()
    # like_ = session.query(db.Fdfs).filter(db.Fdfs.path.like('/root%')).delete(synchronize_session=False)
    return web.json_response({'code': 0, 'msg': data})

@routes.post('/pan/file/upload')
async def upload(request):
    data = await request.post()
    # print('---->%s' % dict(data))
    parent = data['parent']
    upload = data['upload']
    if not isinstance(upload, web.FileField):
        return web.json_response({'code': -1, 'msg': 'access file: %s' % (upload)})
    filename = upload.filename
    content_type = upload.content_type
    upload_file = upload.file
    result = dfs_client.upload_by_buffer(upload_file.read(),filename, parent, content_type)
    if result['status']:
        return web.json_response({'code': 0, 'msg': parent})
    return web.json_response({'code': -1, 'msg': 'failed to upload(%s/%s): %s' % (parent, filename,result['msg'])})

@routes.post('/pan/file/upload_tmpfile')
async def upload_tmpfile(request):
    reader = await request.multipart()
    parent = ''
    tmp_file = ''
    while True:
        part = await reader.next()
        if part is None:
            break
        if part.name == 'parent':
            parent = await part.read(decode=True)
        if part.name == 'upload':
            filename = part.filename
            content_type = part.headers[hdrs.CONTENT_TYPE]
            file_reader = part
            logging.info('----->%s: %s, %s' % (file_reader, filename, content_type))
            size = 0
            tmp_path = '%s/%s' % (os.getcwd(), config['file']['tmp'])
            os.makedirs(tmp_path, exist_ok=True)
            tmp_file= '%s/%s' % (tmp_path, filename)
            with open(tmp_file, 'wb') as dst:
                while True:
                    chunk = await file_reader.read_chunk()  # 8192 bytes by default.
                    if not chunk:
                        dst.flush()
                        break
                    size += len(chunk)
                    dst.write(chunk)
            logging.info('tmp file[size: %s]: %s' % (size, tmp_file))
    # 上传文件
    parent = parent.decode('utf-8')
    result = dfs_client.upload_by_filename(tmp_file, parent, content_type)
    if result['status']:
        logging.info('upload file[%s/%s] success: %s' % (parent, filename, result['msg']))
        return web.json_response({'code': 0, 'msg': parent})
    logging.error('failed to upload file[%s/%s]: %s' % (parent, filename, result['msg']))
    return web.json_response({'code': -1, 'msg': 'failed to upload(%s/%s): %s' % (parent, filename, result['msg'])})

@routes.get('/pan/file/delete')
async def delete(request):
    params = query_string(request)
    path = params.get('path', None)
    if path: 
        parent, name = path.rsplit('/', 1)
        if dfs_client.delete_by_path(parent, name):
            return web.json_response({'code': 0, 'msg': parent})
    return web.json_response({'code': -1, 'msg': 'failed to delete(%s)' % (path)})

@routes.get('/pan/rename')
async def rename(request):
    params = query_string(request)
    fullpath = params['fullpath']
    newname = params['newname']
    result = dfs_client.rename(fullpath, newname)
    if result['status']:
        return web.json_response({'code': 0, 'msg': fullpath.rsplit('/', 1)[0]})
    logging.error('failed to rename file[%s/%s]: %s' % (fullpath, newname, result['msg']))
    return web.json_response({'code': -1, 'msg': 'failed to rename file(%s, %s): %s' % (fullpath, newname, result['msg'])})

@routes.get('/pan/move')
async def move(request):
    params = query_string(request)
    fullpath = params['fullpath']
    newpath = params['newpath']
    result = dfs_client.move(fullpath, newpath)
    if result['status']:
        return web.json_response({'code': 0, 'msg': newpath})
    logging.error('failed to move file[%s/%s]: %s' % (fullpath, newpath, result['msg']))
    return web.json_response({'code': -1, 'msg': 'failed to move file(%s, %s): %s' % (fullpath, newpath, result['msg'])})

@routes.get('/pan/offline')
async def offline(request):
    params = query_string(request)
    parent = params['parent']
    url = params['url']
    if len(url) <= 0 or '/' not in url:
            return web.json_response({'code': -1, 'msg': 'Wrong url (%s)' % url})
    result = dfs_client.offline(parent, url)
    if result['status']:
        return web.json_response({'code': 0, 'msg': parent})
    logging.error('failed to offline download file[%s/%s]: %s' % (parent, url, result['msg']))
    return web.json_response({'code': -1, 'msg': 'failed to offline download file(%s, %s): %s' % (parent, url, result['msg'])})

@routes.get('/pan/mkdir/{name}')
async def mkdir(request):
    name = request.match_info['name']
    params = query_string(request)
    parent = params['parent']
    result = dfs_client.makedir(parent, name)
    if result['status']:
        return web.json_response({'code': 0, 'msg': parent})
    return web.json_response({'code': -1, 'msg': 'failed to makedir[%s, %s]: %s' % (parent, name, result['msg'])})

@routes.get('/pan')
@aiohttp_jinja2.template('pan.html')
async def root(request):
    params = query_string(request)
    path = params.get('path', '/root')
    data = dfs_client.goto_dir(path)
    data['dfsurl'] = config['fdfs']['http_server']
    return data
